ihelpuoo.namespace("ihelpuoo.widget.list");

/**
 * ListView work with queryBeansFromDatabase action.
 * 
 * @param gasket: HTML element object indicate where to draw the view
 * @param name: A unique name to identify the view
 * @param patternName: A full pattern name as the shell of the view. null as default 
 * @param elementName: The XML element name in server response
 * @param moduleName: Which moudle the list associate
 * @param queryActionName: Which action to process query
 * @param deleteActionName: Which action to process delete
 * @param searcherPatternName: Indiate the searcher pattern name. If you don't wanna
 * 				               a searcher, set null
 * @param searcherMapping: which data fields you wanna get from search pattern. Comma separated
 * 						   string, each item is the pattern path key name.
 * @param pagerPatternName: Indiate the pager pattern name. If you don't wanna
 * 				            a searcher, set null
 * @param itemPatternName: Indidate the list item pattern. null as default
 * @param fParseData: A call back function to indicate how to parse a data item.
 * @param fRenderSub: A call back function to didicate how to draw a item in list.
 */
ihelpuoo.widget.list.ListView = function(gasket
										,name
										,patternName
										,elementName
										,moduleName
										,queryActionName
										,deleteActionName
										,searcherPatternName
										,searcherMapping
										,pagerPatternName
										,itemPatternName
										,fParseData
										,fRenderSub
										,fAfterDelete
										,fCustomizeSearcher
										,fCustomizePager
										,pagesize)
{
	// Attributes ...
	this.gasket = gasket;
	this.patternName = patternName;
	this.searcherPatternName = searcherPatternName;
	this.pagerPatternName = pagerPatternName;
	this.searcherMapping = searcherMapping;
	this.name = name;
	this.moduleName = moduleName;
	this.elementName = elementName;
	this.queryActionName = queryActionName;
	this.deleteActionName = deleteActionName;
	this.itemPatternName = (null==itemPatternName?"eve.pattern.list.Item":itemPatternName);
	// Elements ...
	this.oArena = null;
	this.oToolbar = null;
	// Inner data
	this.list = null;
	this.pn = 1;
	this.rnum = 0;
	this.pnum = 0;
	this.pagesize = (pagesize>0?pagesize:20);
	this.activeId = -1;
	this.shouldActiveId = -1;
	// callbacks...
	this.fParseData = fParseData;
	this.fRenderSub = fRenderSub;
	this.fAfterDelete = fAfterDelete;
	this.fCustomizeSearcher = fCustomizeSearcher;
	this.fCustomizePager = fCustomizePager;
}

ihelpuoo.widget.list.ListView.prototype
=
{
	init: function()
	{
		if(this.hasBeanInit)return;
		this.view = new ihelpuoo.widget.View(this.gasket
											,(null==this.patternName?
												"eve.pattern.list.Shell"
												:this.patternName));
		// Sub Views ...
		this.children = null;
		this.initViews();
		this.oSearcher = this.view.getElement("searcher");
		if(this.oSearcher)
			if(this.searcherPatternName)
			{
				this.searcher = new ihelpuoo.widget.list
											.SearcherView(this.oSearcher
														 ,this.searcherPatternName
														 ,this.searcherMapping);
				this.searcher.parent = this;
				if(this.fCustomizeSearcher)
					this.fCustomizeSearcher(this.searcher);
				this.searcher.draw();
			}
			else
			{
				this.oSearcher.style.display="none";
				this.searcher = null;
			}
		
		this.oPager = this.view.getElement("pager");
		if(this.oPager)
			if(this.pagerPatternName)
			{
				this.pager = new ihelpuoo.widget.list
									.PagerView(this.oPager,this.pagerPatternName);
				this.pager.parent = this;
				if(this.fCustomizePager)
					this.fCustomizePager(this.pager);
				this.pager.draw(this);
			}
			else
			{
				this.oPager.style.display="none";
				this.pager = null;
			}
		
		this.bundleEvents();
		if(!this.oShowAll && !this.oCancelAll && !this.oSelectAll && this.oToolbar)
			this.oToolbar.style.display = "none";
		
		this.hasBeanInit = true;
		// register
		if(this.name)
			ihelpuoo.widget.registerView2(this);
	}
	
	
	/**
	 * Make current list reload data from server
	 */
	,
	reload : function()
	{
		var url = ihelpuoo.http.server().url(this.moduleName,this.queryActionName);
		var postStr = "";
		if(this.searcher!=null)
			postStr = this.searcher.getPostString();
		else if(this.filterString)
			postStr = this.filterString;

		postStr = (!ihelpuoo.isBlank(postStr)
						?
						postStr+"&pn="+this.pn+"&pagesize="+this.pagesize
						:"pn="+this.pn+"&pagesize="+this.pagesize
				   );

		if(ihelpuoo.isInfoEnabled())
			ihelpuoo.info(" -> " + url + (ihelpuoo.isBlank(postStr)?"":"?" +postStr));

		var doc = ihelpuoo.http.POSTXML(url,postStr);
		if(null!=doc && ihelpuoo.isObject(doc))
		{
			this.pn = ihelpuoo.xml.getAttributeAsInteger(doc.documentElement,"pn",1);
			this.rnum = ihelpuoo.xml.getAttributeAsInteger(doc.documentElement,"rnum",0);
			this.pnum = ihelpuoo.xml.getAttributeAsInteger(doc.documentElement,"pnum",0);
			this.pagesize = ihelpuoo.xml.getAttributeAsInteger(doc.documentElement,"pagesize",this.pagesize);
		
			var nodeList = doc.documentElement.getElementsByTagName(this.elementName);
			
			if(ihelpuoo.isDebugEnabled())
				ihelpuoo.debug("Got " + nodeList.length + " items!");
			
			this.list = new Array();
			for(var i=0;i<nodeList.length;i++)
			{
				var node = nodeList.item(i);
				var data = this.fParseData(node);
				this.list.push(data);
			}
			return true;
		}
		return false;
	}
	/**
	 * clear sub nodes
	 */
	,
	clear : function()
	{
		if(null!=this.oArena)
			ihelpuoo.dom.clearAllChildren(this.oArena);
		this.children = new Array();
	}
	
	,
	isEmpty: function()
	{
		if(null==this.children || this.children.length==0) return true;
		return false;
	}
	
	,
	isActived : function(itemId)
	{
		return this.activeId == itemId;
	}
	
	,
	hasActived : function()
	{
		return this.activeId>0;
	}
	
	,
	setActive : function(itemId,obj)
	{
		this.disActiveItem();
		this.activeId = itemId;
		var index = this.getIndexById(itemId);
		var itemView = this.getChildByIndex(index);
		if(itemView)
		{
			itemView.active();
			if(obj)
			{
				itemView.draw(obj,this.fRenderSub);
				this.list[index] = obj;
			}
			return itemView;
		}
		return null;
	}
	
	,
	disActiveItem : function()
	{
		if(!this.hasActived()) return;
		var a = this.getChildById(this.activeId);
		if(a)
			a.disactive();
		this.activeId = -1;
	}
	
	,
	getChildById : function(itemId)
	{
		for(var i=0;i<this.children.length;i++)
		{
			if(this.children[i].getId() == itemId)
				return this.children[i];
		}
		return null;
	}
	
	,
	getChildByIndex : function(index)
	{
		if(!this.children)return null;
		if(index<0) return null;
		if(index>=this.children.length) return null;
		return this.children[index];
	} 
	
	,
	getIndexById : function(itemId)
	{
		if(!this.list) return -1;
		for(var i=0;i<this.list.length;i++)
		{
			if(this.list[i].id == itemId)
				return i;
		}
		return -1;
	}
	
	,
	selectAll : function()
	{
		if(null==this.children || this.children.length==0) return ;
		for(var i=0;i<this.children.length;i++)
		{
			 this.children[i].markSelected();
		}
	}
	
	,
	onSelectAll : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		if(null!=v)
			v.selectAll();
	}
	
	,
	onCancelAll : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		if(null!=v)
			v.cancelAll();
	}
	
	,
	cancelAll : function()
	{
		if(null==this.children || this.children.length==0) return ;
		for(var i=0;i<this.children.length;i++)
		{
			 this.children[i].unMarkSelected();
		}
	}
	
	,
	getCheckedIds : function()
	{
		if(null==this.children || this.children.length==0) return null;
		
		re = "";
		for(var i=0;i<this.children.length;i++)
		{
			if(this.children[i].isSelected())
				re += this.children[i].getId()+",";
		}
		
		if(re.length==0) return null;
		
		return re.substring(0,re.length-1);
	}
	
	,
	initViews : function()
	{
		if(this.view.isNeverBeDrawn())
		{
			this.view.preparePattern();
			this.oArena = this.view.getElement("arena");
			this.oToolbar = this.view.getElement("toolbar");
			this.oShowAll = this.view.getElement("toolbar");
			this.oSelectAll = this.view.getElement("selectAll");
			this.oCancelAll = this.view.getElement("cancelAll");
			this.view.hide();
		}
	}
	
	,
	bundleEvents : function()
	{
		ihelpuoo.widget.addViewEventByKey(this,"selectAll","click",this.onSelectAll);
		ihelpuoo.widget.addViewEventByKey(this,"cancelAll","click",this.onCancelAll);
		ihelpuoo.widget.addViewEventByKey(this,"showAll","click",this.onShowAll);
		
		if(this.searcher)
		{
			var btn = this.searcher.getElement("go");
			ihelpuoo.widget.setViewNameToElement(btn,this);
			ihelpuoo.event.add(btn,"click",this.onSearch);
			
			btn = this.searcher.getElement("goIcon");
			if(btn)
			{
				ihelpuoo.widget.setViewNameToElement(btn,this);
				ihelpuoo.event.add(btn,"click",this.onSearch);
			}
		}
		
		if(this.pager)
		{
			ihelpuoo.widget.addViewEvent(this,this.pager.oFirst,"click",this.onFirst);
			ihelpuoo.widget.addViewEvent(this,this.pager.oLast,"click",this.onLast);
			ihelpuoo.widget.addViewEvent(this,this.pager.oPrev,"click",this.onPrev);
			ihelpuoo.widget.addViewEvent(this,this.pager.oNext,"click",this.onNext);
			ihelpuoo.widget.addViewEvent(this,this.pager.oGoto,"click",this.onRefresh);
		}
	}
	
	,
	onShowAll: function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		v.showAll();
	}
	
	,
	showAll: function()
	{
		if(this.searcher)
		{
			this.searcher.clear();
			this.refresh();
		}
	}
	
	,
	checkPagerReset: function()
	{
		this.pn = this.pager.getInt("pn",1);
		var size = this.pager.getInt("pagesize",this.pagesize);
		if(this.pn>0 && size!=this.pagesize)
		{
			this.pn = 1;
			this.pagesize = size;
			return true;
		}
		this.pagesize = size;
		return false;
	}
	
	,
	prev : function()
	{
		this.checkPagerReset();
		if(this.pn==0)return;
		if(this.pn>1) this.pn--;
		this.pager.draw(this);
		this.refresh();
	}
	
	,
	onPrev : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		v.prev();
	}
	
	,
	next : function()
	{
		var pagerHasBeenReseted = this.checkPagerReset();
		if(this.pn==0)return;
		if(!pagerHasBeenReseted && this.pn<this.pnum)
			this.pn++;
		this.pager.draw(this);
		this.refresh();
	}
	
	,
	onNext : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		v.next();
	}
	
	,
	first : function()
	{
		this.checkPagerReset();
		if(this.pn==0)return;
		this.pn = 1;
		this.pager.draw(this);
		this.refresh();
	}
	
	,
	onFirst : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		v.first();
	}
	
	,
	last : function()
	{
		var pagerHasBeenReseted = this.checkPagerReset();
		if(this.pn==0)return;
		if(this.pn==this.pnum) return;
		if(!pagerHasBeenReseted)
			this.pn = (this.pnum>0?this.pnum:1);
		this.pager.draw(this);
		this.refresh();
	}
	
	,
	onLast : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		v.last();
	}
	
	,
	refresh : function()
	{
		if(this.reload())
		{
			this.clear();
			this.draw();
		}
	}
	
	,
	onRefresh : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		v.checkPagerReset();
		v.refresh();
	}
	
	,
	onSearch : function()
	{
		var v = ihelpuoo.widget.getViewByEventSource(this);
		v.checkPagerReset();
		if(v.pn>1)
		{
			v.pn = 1;
			if(v.pager)
				v.pager.draw(v);
		}
		v.refresh();
	}
	
	,
	draw : function()
	{
		this.init();
		this.view.display();	
	
		if(null==this.list || this.list.length==0)
		{
			if(ihelpuoo.isInfoEnabled())
				ihelpuoo.info("Empty item list!");
			if(null!=this.pager)
				this.pager.draw(this);
			if(this.afterDraw) this.afterDraw(this);
			return;				
		}
		this.children = new Array();
		var av = new ihelpuoo.widget.list.ListItemView(this);
		av.draw(this.list[0],this.fRenderSub);
		if(this.activeId==av.getId())
		{
			av.active();
		}
		this.children.push(av);
		if(null!=av.oCheckbox && this.oToolbar)
			this.oToolbar.style.display="block";
		
		for(var i=1;i<this.list.length;i++)
		{
			av = new ihelpuoo.widget.list.ListItemView(this);
			av.draw(this.list[i],this.fRenderSub);
			if(this.activeId==av.getId())
			{
				av.active();
			}
			this.children.push(av);
		}
		
		if(null!=this.pager)
			this.pager.draw(this);
		if(this.oToolbar && isIE)
			this.oToolbar.style.width="100%";

		if(this.afterDraw)
		{
			if(ihelpuoo.isDebugEnabled()) ihelpuoo.debug("-> after draw...");
			this.afterDraw(this);
		}
	}
		
	,
	drawNew: function(obj,pattern)
	{
		if(!obj)
			return;
		if(!this.children)
			this.children = new Array();
		if(!this.list)
			this.list = new Array();
		this.list.push(obj);
		var av = new ihelpuoo.widget.list.ListItemView(this,(pattern?pattern:"eve.pattern.list.NewItem"));
		av.draw(obj,this.fRenderSub);
		this.children.push(av);
		this.setActive(obj.id);
	}
	
	,
	deleteCheckedItems : function()
	{
		if(!this.deleteActionName)
			return;
		var ids = this.getCheckedIds();
		if(ids && ids.length>0)
		{
			if(!confirm(this.view.shell.getAttribute("msg-confirm"))) return;
			var url = ihelpuoo.http.server().url(this.moduleName,this.deleteActionName);
			if(ihelpuoo.isInfoEnabled())
				ihelpuoo.info(" -> " + url);
			this.shouldActiveId = -1;
			if(this.hasActived())
			{
				var activedItem = this.getChildById(this.activeId);
				if(activedItem && !activedItem.isSelected())
					this.shouldActiveId = this.activeId;
				else
				{
					var firstSelected = -1;
					for(var i=0;i<this.children.length;i++)
					{
						if(this.children[i].isSelected())
						{
							firstSelected = i;
							break;
						}
					}
					for(var i=firstSelected+1;i<this.children.length;i++)
						if(!this.children[i].isSelected())
						{
							this.shouldActiveId =this.children[i].getId();
							break;
						}
					if(this.shouldActiveId<0)
						for(var i=firstSelected-1;i>=0;i--)
							if(!this.children[i].isSelected())
							{
								this.shouldActiveId =this.children[i].getId();
								break; 
							}
				}
			}
			var xml = ihelpuoo.http.POSTXML(url,"ids="+ids);
			if(null!=xml && ihelpuoo.isObject(xml))
			{
				this.refresh();
				if(this.fAfterDelete)
					this.fAfterDelete(ids);
			}
		}
	}
	
	// <WEBOO:INHERIT extends="ihelpuoo.widget.View">
	,display: function(){this.view.display();}
	,getElement: function(key){return this.view.getElement(key);}
	,isNeverBeDrawn: function(){return this.view.isNeverBeDrawn();}
	,preparePattern: function(){this.view.preparePattern();}
	,isHidden: function(){return this.view.isHidden();}
	,hide: function(){this.view.hide();}
	,set: function(key,value){this.view.set(key,value);}
	,getString: function(key,defValue){return this.view.getString(key,defValue);}
	,getInt: function(key,defValue){return this.view.getInt(key,defValue);}
	,getBoolean: function(key,defValue){return this.view.getBoolean(key,defValue);}
	,addEvent: function(key,eventName,fnHandler,bCapture){this.view.addEvent(key,eventName,fnHandler,bCapture);}
	,removeEvent: function(key,eventName,fnHandler,bCapture){this.view.removeEvent(key,eventName,fnHandler,bCapture);}
	// </WEBOO:INHERIT>
}